package clientermi.clienteSocket;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.BindException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import javax.swing.JOptionPane;
import javax.net.ssl.*;
import javax.net.SocketFactory;

/**
 * Clase que implementa el cliente de socket
 * @author Jorge Hernán Londoño Echeverri narzyx@gmail.com Hayner Benavides Moreno hayner2005@gmail.com
 */
public class ClienteSocket {

    private Socket s;
   // private SocketFactory factory;
    private int port;
    private String ip;
    private PrintWriter pw;
    private BufferedReader br;

    public ClienteSocket(String ip, int p){
        
        s = null;
        port = p;
        this.ip = ip;
        pw = null;
        br = null;
       // factory=SocketFactory.getDefault();
    }
    /**
     * Método que inicaliza la conexión
     * @return boolean true si conecta, false en caso contrario
     */
    public boolean init(){
        boolean inicializacion=true;
        try{            
            if(establecerConexion()){
                pw = new PrintWriter(s.getOutputStream(),true);
                br = new BufferedReader(new InputStreamReader(s.getInputStream()));
            }
            else
                return false;
        }
        catch(Exception e){
            inicializacion=false;
            e.printStackTrace();
        }

        return inicializacion;
    }
    /**
     * Método que establece la conexión del socket
     * por medio del puerto y la IP
     * @return boolean true conexión éxitosa, false caso contrario
     */
    public boolean establecerConexion(){
        try{
            //SocketFactory factory= SSLSocketFactory.getDefault();
            //s=factory.createSocket(ip, port);
            s=new Socket(ip,port);

        }
        catch(UnknownHostException uke){
            System.out.println("no encontro el host");
            //uke.printStackTrace();
            return false;
        }
        catch(IOException ioe){
            System.out.println("fallo IO");
            //ioe.printStackTrace();
            return false;
        }

        return true;
    }
    /**
     * Método que permite registrar elcliente
     * @param puerto
     */
    public String registrar(String ip,int puerto){
        try{       
             
              pw.println(construirCadenaRegistro(ip,puerto));
              String entrada= br.readLine();
              if(entrada!=null){
                  return entrada.trim();
                   // 
                  
              }              
               //s.close();
               //pw.close();
               //br.close();
        }
        catch(IOException ioe){
            System.out.println("Ha ocurrido un error en las entradas/ salidas");

        }
        return "";
    }
    /**
     * método que obtiene la lista de cientes
     * que se encuentran actualmente conectados
     * al servidor de indices
     * @return String lista de clientes conectados
     */
    public String obtenerListados(){
        String cadena = "";
        try{
            pw.println("LISTAR");
            cadena = br.readLine();
            if(cadena!=null){
              System.out.println(cadena);
            }
        }
        catch(IOException ioe){
            System.out.println("Ha ocurrido un error en las entradas/ salidas");

        }        
       return cadena;
    }
    /**
     * Método que permite la creación los registros que contiene los
     * clientes que se encuentran actualmente conectados, por medio
     * del siguientes formato
     * Registro: IP|puerto
     * cliente1@cliente2@cliente3..... cliente n
     * @param cadena
     * @return ArrayList<Registro> lista de clientes conectados
     */
    public ArrayList<Registro> construirLista(String cadena) {
        String [] registros = cadena.split("\\@");
        ArrayList<Registro> listaRegistros = new ArrayList<Registro>();

        for(String registro : registros) {
            String [] campos = registro.split("\\|");
            if(campos.length>1){
                Registro registroObj = new Registro(campos[0], Integer.parseInt(campos[1]));
                listaRegistros.add(registroObj);
            }
        }
        return listaRegistros;


    }
    /**
     * Método que permite desocnectar un socket
     */
    public void desconectar(){
        try{
            s.close();
            pw.close();
            br.close();
        }catch(IOException ioe){
            //ioe.printStackTrace();
        }
    }
    /**
     * Método que permite construir la cadena con el formato
     * para que este se pueda registrar
     * REGISTRAR|IP|puerto
     * @param puerto
     * @return String cadena de registro
     */
    public String construirCadenaRegistro(String ip,int puerto){
        String registro="REGISTRAR|";
        try{
           
            registro += ip +"|";
        }
        catch(Exception uhe){
            uhe.printStackTrace();
        }
        registro += puerto;
        return registro ;
    }

}
